/*
 * Sensor.c
 *
 *  Created on: 2025年10月25日
 *      Author: feng
 */
#include "esp_log.h"
#include "esp_system.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "string.h"
#include "driver/gpio.h"
#include "driver/i2c_master.h"

#include "BSP.h"
#include <stdint.h>
#include <math.h>


#define SensorPowerPin  			GPIO_NUM_5									//传感器电源控制引脚
#define SensorPowerOn  				gpio_set_level(SensorPowerPin, 1)			//打开传感器电源
#define SensorPowerOff  			gpio_set_level(SensorPowerPin, 0)			//关闭传感器电源

#define I2C_SCL_Pin  				GPIO_NUM_7									//I2C SCL引脚
#define I2C_SDA_Pin  				GPIO_NUM_6									//I2C SDA引脚




static i2c_master_bus_handle_t i2c_bus_handle;
static i2c_master_dev_handle_t i2c_dev_handle;





/*	系统参数	*/
extern SystemParameter SysParam;
/*	系统状态	*/
extern SystemState SysState;

extern const char *TAG;





/**
  * @brief  中位值平均滤波法
  * @param  None
  * @retval None
  */
static uint32_t MedianFilter( uint32_t *data, uint32_t size )
{
	uint32_t max, min;
	uint32_t sum, i;
	
	if( size > 2 )
	{
		max = data[0];
		min = max;
		sum = 0;
		
		for( i=0; i<size; i++ )
		{
			sum += data[i];
			
			if( data[i] > max ) max = data[i];
			
			if( data[i] < min ) min = data[i];
		}
		
		sum = sum - max - min;
		
		return( sum/(size-2) );
	}
		
	return 0;
}




/**
	* @brief 	计算饱和水汽压(℃) - Magnus公式
	* @param  T：干球温度
	* @retval 饱和水汽压
	*/
static double saturation_vapor_pressure(double T) {
  return 0.6112 * exp((17.62 * T) / (T + 243.12));
}



/**
	* @brief 	湿球温度计算（迭代法）
	* @param  dry_temp：干球温度
  	* @param  rh：相对湿度
  	* @param  pressure：大气压，单位：kPa
	* @retval 湿球温度
	*/
double calc_wet_bulb_temp(double dry_temp, double rh, double pressure)
{
    // 处理边界情况
    if (rh <= 0.0) return dry_temp;  // 零湿度时湿球温度等于干球温度
    if (rh >= 100.0) return dry_temp; // 饱和湿度时两者相等
    
    // 计算实际水汽压
    double es_dry = saturation_vapor_pressure(dry_temp);
    double e = rh / 100.0 * es_dry;
    
    // 计算湿度计算常数 (hPa/°C)
    double gamma = 0.00066 * pressure;
    
    // 使用二分法求解湿球温度
    double low = -50.0;      // 理论最小可能值
    double high = dry_temp;  // 湿球温度不会超过干球温度
    double tw, f_tw;
    int max_iter = 50;
    double tolerance = 0.001;
    
    for (int i = 0; i < max_iter; i++) {
        tw = (low + high) / 2.0;
        double es_wet = saturation_vapor_pressure(tw);
        
        // 湿球温度方程：es_wet = e + gamma * (dry_temp - tw)
        f_tw = es_wet - e - gamma * (dry_temp - tw);
        
        // 更新二分区间
        if (f_tw > 0.0) {
            high = tw;  // 函数值太大，降低上限
        } else {
            low = tw;   // 函数值太小，提高下限
        }
        
        // 检查收敛
        if (high - low < tolerance) {
            break;
        }
    }
    
    return (low + high) / 2.0;
}



/**
	* @brief 	露点温度计算（迭代法）
	* @param  dry_temp：干球温度
  	* @param  rh：相对湿度
	* @retval 露点温度
	*/
double calc_dew_point_temp(double dry_temp, double rh) {
    // 处理边界情况
    if (rh <= 0.0) return -273.15;
    if (rh >= 100.0) return dry_temp;
    
    // 计算实际水汽压
    double es = saturation_vapor_pressure(dry_temp) * 10.0;
    double e = rh / 100.0 * es;
    
    // 牛顿迭代法求解
    double td = dry_temp;  // 初始猜测：干球温度
    double tolerance = 0.0001;  // 收敛阈值
    int max_iter = 20;         // 最大迭代次数
    
    for (int i = 0; i < max_iter; i++) {
        // 计算当前饱和水汽压
        double es_td = saturation_vapor_pressure(td) * 10.0;
        
        // 计算函数值 f(td) = es(td) - e
        double f = es_td - e;
        
        // 计算导数 f'(td) = des/dtd
        double numerator_deriv = 17.62 * 243.12;
        double denominator_deriv = (td + 243.12) * (td + 243.12);
        double df = es_td * (numerator_deriv / denominator_deriv);
        
        // 牛顿迭代: td_new = td - f/df
        double td_new = td - f / df;
        
        // 检查收敛
        if (fabs(td_new - td) < tolerance) {
            return td_new;
        }
        
        // 确保温度在合理范围内
        if (td_new > dry_temp) td_new = dry_temp - 0.1;
        if (td_new < -100.0) td_new = -99.9;
        
        td = td_new;
    }
    
    return td; // 返回最后一次迭代结果
}



/**
	* @brief 	含湿量计算 (g/kg)
	* @param  T：干球温度
  	* @param  RH：相对湿度
  	* @param  P：大气压，单位：kPa
	* @retval 含湿量
	*/
double calc_humidity_ratio(double T, double RH, double P) {
    double es = saturation_vapor_pressure(T);
    double e = es * RH / 100.0;
    return 622 * e / (P - e);  // W = 622 * e / (P - e)
}




/**
	* @brief 	焓值计算 (kJ/kg_da)
	* @param  T：干球温度
  	* @param  RH：相对湿度
  	* @param  P：大气压，单位：kPa
	* @retval 焓值
	*/
double calc_enthalpy(double T, double RH, double P) {
    double W = calc_humidity_ratio(T, RH, P) / 1000.0;
    return 1.006 * T + W * (2501 + 1.86 * T);  // h = c_p*T + W*(L + c_pv*T)
}




/**
  * @brief  CRC校验
  * @param  data：要校验的数据
  * @param  len：数据长度
  * @retval None
  */
static uint8_t sht_crc8(const uint8_t *data, uint8_t len) {
    uint8_t crc = 0xFF;
    for (uint8_t i = 0; i < len; i++) {
        crc ^= data[i];
        for (uint8_t j = 0; j < 8; j++) {
            if (crc & 0x80)
                crc = (crc << 1) ^ 0x31;
            else
                crc <<= 1;
        }
    }
    return crc;
}




/**
  * @brief  初始化传感器接口
  * @param  None
  * @retval None
  */
void Sensor_GPIO_Init( void )
{
	gpio_config_t io_conf = {};
	
	/*  初始化传感器电源控制引脚 */
	//disable interrupt
    io_conf.intr_type = GPIO_INTR_DISABLE;
    //set as output mode
    io_conf.mode = GPIO_MODE_OUTPUT;
    //bit mask of the pins that you want to set
    io_conf.pin_bit_mask = (1ULL<<SensorPowerPin);
    //disable pull-down mode
    io_conf.pull_down_en = GPIO_PULLDOWN_ENABLE;
    //disable pull-up mode
    io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
    //configure GPIO with the given settings
    gpio_config(&io_conf);
    
    SensorPowerOff;					//关闭传感器电源 
}




/**
  * @brief  初始化I2C总线
  * @param  None
  * @retval None
  */
static void I2C_Init( void )
{
	/* 创建I2C总线 */
	i2c_master_bus_config_t i2c_bus_config = {
        .clk_source = I2C_CLK_SRC_DEFAULT,
        .i2c_port = -1,
        .scl_io_num = I2C_SCL_Pin,
        .sda_io_num = I2C_SDA_Pin,
        .glitch_ignore_cnt = 7,
    };
    
    ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_config, &i2c_bus_handle));
    
    
    /* 在I2C总线中添加设备 */
    i2c_device_config_t TempSensor = {
		.dev_addr_length = I2C_ADDR_BIT_LEN_7,
		.device_address = 0x44,
		.scl_speed_hz = 100000,
		.scl_wait_us = 0,
		
	};
	
    ESP_ERROR_CHECK( i2c_master_bus_add_device(i2c_bus_handle, &TempSensor, &i2c_dev_handle) );
}



/**
  * @brief  I2C总线释放
  * @param  None
  * @retval None
  */
static void I2C_Deinitialize( void )
{
	i2c_master_bus_rm_device( i2c_dev_handle );
	i2c_del_master_bus(i2c_bus_handle);
}





/**
  * @brief  获取SHT30温湿度
  * @param  temp：存放读到的温度
  * @param  rh：存放读到的湿度
  * @retval   - ESP_OK 
  *           - ESP_FAIL 
  */
static esp_err_t  SHT30_Measure( uint16_t *temp, uint16_t *rh )
{
	esp_err_t err;
	uint8_t write_buffer[2] = { 0 };
	uint8_t read_buffer[6] = { 0 };
	uint8_t sum = 0;
	uint16_t value = 0;
	
	
	write_buffer[0] = 0x24;
	write_buffer[1] = 0x00;
	
	err = i2c_master_transmit( i2c_dev_handle, write_buffer, 2, 10);
	if( err != ESP_OK ) return err;
	
	vTaskDelay( 20 / portTICK_PERIOD_MS );
	
	err = i2c_master_receive( i2c_dev_handle, read_buffer, 6, 10);
	if( err != ESP_OK ) return err;
	
	sum = sht_crc8( &read_buffer[0], 2);
	if( sum != read_buffer[2] ) return ESP_FAIL;
	
	sum = sht_crc8( &read_buffer[3], 2);
	if( sum != read_buffer[5] ) return ESP_FAIL;
	
	
	value = read_buffer[0];
	value = value << 8;
	value = value | read_buffer[1];
	
	if( (value >= 58046) || (value <= 5617) ) return ESP_FAIL;
	
	*temp = value;	//温度赋值
	
	
	value = read_buffer[3];
	value = value << 8;
	value = value | read_buffer[4];
	*rh = value;	//湿度赋值
	
	return ESP_OK;
}





/**
  * @brief  获取SHT41温湿度
  * @param  temp：存放读到的温度
  * @param  rh：存放读到的湿度
  * @retval   - ESP_OK 
  *           - ESP_FAIL 
  */
static esp_err_t  SHT41_Measure( uint16_t *temp, uint16_t *rh )
{
	esp_err_t err;
	uint8_t write_buffer[2] = { 0 };
	uint8_t read_buffer[6] = { 0 };
	uint8_t sum = 0;
	uint16_t value = 0;
	
	write_buffer[0] = 0xfd;
	
	err = i2c_master_transmit( i2c_dev_handle, write_buffer, 1, 10);
	if( err != ESP_OK ) return err;
	
	vTaskDelay( 20 / portTICK_PERIOD_MS );
	
	err = i2c_master_receive( i2c_dev_handle, read_buffer, 6, 10);
	if( err != ESP_OK ) return err;
	
	sum = sht_crc8( &read_buffer[0], 2);
	if( sum != read_buffer[2] ) return ESP_FAIL;
	
	sum = sht_crc8( &read_buffer[3], 2);
	if( sum != read_buffer[5] ) return ESP_FAIL;
	
	value = read_buffer[0];
	value = value << 8;
	value = value | read_buffer[1];
	
	if( (value >= 58046) || (value <= 5617) ) return ESP_FAIL;
	
	*temp = value;
	
	value = read_buffer[3];
	value = value << 8;
	value = value | read_buffer[4];
	
	if( value >= 55574 ) *rh = 55574;
	else if( value <= 3146 ) *rh = 3146;
	else *rh = value;
	
	return ESP_OK;
}



/**
  * @brief 获取温湿度数据
  * @param  SensorType：传感器类型
  * @param  Temp：读取的温度数值
  * @param  RH：读取的湿度数值
  * @retval   - ESP_OK 
  *           - ESP_FAIL 
  */
static esp_err_t GetSensorData( uint8_t SensorType, float *Temp, float *RH )
{
	esp_err_t err;
	uint8_t i = 0;
	uint16_t temperature = 0;
	uint16_t humidity = 0;
	uint32_t Temperature[5];
	uint32_t Humidity[5];
	uint32_t buf[50] = { 0 };
	uint32_t value1 = 0;
	uint32_t value2 = 0;
	static uint32_t sum[8] = { 0 };
	static uint8_t count[8] = { 0 };
	static uint32_t win_buf[8][50] = { 0 };
	
	if( SensorType == SHT30 )
	{
		for( i=0; i<5; i++ )
		{
			vTaskDelay( 10 / portTICK_PERIOD_MS );	

			err = SHT30_Measure( &temperature, &humidity );	//获取SHT30温湿度

			if( err == ESP_OK ) 
			{
				Temperature[i] = temperature;
				Humidity[i] = humidity;
			}
			else return err;
		}

		temperature = MedianFilter( Temperature, 5 );
		humidity = MedianFilter( Humidity, 5 );

		// err = SHT30_Measure( &temperature, &humidity );	 //获取SHT30温湿度
	}
	else 
	{
		for( i=0; i<5; i++ )
		{
			vTaskDelay( 10 / portTICK_PERIOD_MS );	

			err = SHT41_Measure( &temperature, &humidity );	// 获取SHT41温湿度

			if( err == ESP_OK ) 
			{
				Temperature[i] = temperature;
				Humidity[i] = humidity;
			}
			else
			{
				return err;
			} 
		}

		temperature = MedianFilter( Temperature, 5 );
		humidity = MedianFilter( Humidity, 5 );


		// err = SHT41_Measure( &temperature, &humidity );	// 获取SHT41温湿度
	}
	
	// if( err != ESP_OK ) 
	// {
	// 	return err;
	// }
	
	
	/*	对温度数据做移动平均处理	*/
	if( count[0] < SysParam.AppParam.AverageWindowSize )
	{
		win_buf[0][count[0]] = temperature;
		sum[0] += win_buf[0][count[0]];
		count[0]++;
		value1 = sum[0] / count[0];
	}
	else
	{
		memcpy( buf, &win_buf[0][1], ( (SysParam.AppParam.AverageWindowSize-1) * 4 ) );
		memcpy( &win_buf[0][0], buf, ( (SysParam.AppParam.AverageWindowSize-1) * 4 ) );
		win_buf[0][SysParam.AppParam.AverageWindowSize-1] = temperature;
		value1 = MedianFilter( &win_buf[0][0], SysParam.AppParam.AverageWindowSize );
	}
	
	
	/*	对湿度数据做移动平均处理	*/
	if( count[1] < SysParam.AppParam.AverageWindowSize )
	{
		win_buf[1][count[1]] = humidity;
		sum[1] += win_buf[1][count[1]];
		count[1]++;
		value2 = sum[1] / count[1];
	}
	else
	{
		memcpy( buf, &win_buf[1][1], ( (SysParam.AppParam.AverageWindowSize-1) * 4 ) );
		memcpy( &win_buf[1][0], buf, ( (SysParam.AppParam.AverageWindowSize-1) * 4 ) );
		win_buf[1][SysParam.AppParam.AverageWindowSize-1] = humidity;
		value2 = MedianFilter( &win_buf[1][0], SysParam.AppParam.AverageWindowSize );
	}
	
	
	if( SensorType == SHT30 )
	{
		*Temp = -45.0 + 175.0 * ( (float)value1 / 65535.0 );
		*RH = 100.0 * (float)value2 / 65535.0;
		
		// ESP_LOGI(TAG, "temperature: %0.2f; humidity:  %0.2f\r\n", *Temp, *RH);
	}
	else
	{
		*Temp = -45.0 + 175.0 * ( (float)value1 / 65535.0 );
		*RH = -6.0 + 125.0 * ( (float)value2 / 65535.0 );
		
		// ESP_LOGI(TAG, "temperature: %0.2f; humidity:  %0.2f\r\n", *Temp, *RH);
	}
	
	return err;
}




/**
  * @brief 处理传感器相关事项
  * @param  None
  * @retval  None
  */
void SensorProcess( void )
{
	esp_err_t err;
	float TDB;                    		
	float RH;                    		
	static uint8_t DeviceType = 0;
	static uint8_t SensorType = 0;
	static uint8_t state = 0;
	static uint8_t fault_cnt = 0;
	
	
	switch(state)
	{
		case 0:
		{
			DeviceType = SysParam.WorkParam.DeviceType;
			SensorType = SysParam.WorkParam.SensorType;
			state = 1;
		}
		break;
		
		case 1:
		{
			SensorPowerOn;											//打开传感器电源
			
			vTaskDelay( 1000 / portTICK_PERIOD_MS );				//上电延时
			
			I2C_Init( );											//初始化I2C总线
			
			state = 2;
		}
		break;
		
		case 2:
		{
			err = GetSensorData( SensorType, &TDB, &RH );
			if( err != ESP_OK )										//获取温湿度失败
			{
				fault_cnt++;
				
				if( fault_cnt >= 8 )
				{
					fault_cnt = 0;
					state = 3; 
				}
			}
			else 													//获取温湿度成功
			{
				fault_cnt = 0;
				
				if( DeviceType == AtpsSa )
				{
					SysState.AtpsSaParam.SensorFault = NoFault;
					
					SysState.AtpsSaParam.TDB = TDB + SysParam.AppParam.AtpsSaTempCali;
					SysState.AtpsSaParam.RH = RH + SysParam.AppParam.AtpsSaRhCali;
					SysState.AtpsSaParam.TDP = calc_dew_point_temp(SysState.AtpsSaParam.TDB, SysState.AtpsSaParam.RH);
					SysState.AtpsSaParam.TWB = calc_wet_bulb_temp(SysState.AtpsSaParam.TDB, SysState.AtpsSaParam.RH, SysParam.AppParam.Atmosphere);
					SysState.AtpsSaParam.HR = calc_humidity_ratio(SysState.AtpsSaParam.TDB, SysState.AtpsSaParam.RH, SysParam.AppParam.Atmosphere);
					SysState.AtpsSaParam.H = calc_enthalpy(SysState.AtpsSaParam.TDB, SysState.AtpsSaParam.RH, SysParam.AppParam.Atmosphere);
				}
				else if( DeviceType == AtpsOa )
				{
					SysState.AtpsOaParam.SensorFault = NoFault;
					
					SysState.AtpsOaParam.TDB = TDB + SysParam.AppParam.AtpsOaTempCali;
					SysState.AtpsOaParam.RH = RH + SysParam.AppParam.AtpsOaRhCali;
					SysState.AtpsOaParam.TDP = calc_dew_point_temp(SysState.AtpsOaParam.TDB, SysState.AtpsOaParam.RH);
					SysState.AtpsOaParam.TWB = calc_wet_bulb_temp(SysState.AtpsOaParam.TDB, SysState.AtpsOaParam.RH, SysParam.AppParam.Atmosphere);
					SysState.AtpsOaParam.HR = calc_humidity_ratio(SysState.AtpsOaParam.TDB, SysState.AtpsOaParam.RH, SysParam.AppParam.Atmosphere);
					SysState.AtpsOaParam.H = calc_enthalpy(SysState.AtpsOaParam.TDB, SysState.AtpsOaParam.RH, SysParam.AppParam.Atmosphere);
				}
				else if( DeviceType == AtpsRa )
				{
					SysState.AtpsRaParam.SensorFault = NoFault;
					
					SysState.AtpsRaParam.TDB = TDB + SysParam.AppParam.AtpsRaTempCali;
					SysState.AtpsRaParam.RH = RH + SysParam.AppParam.AtpsRaRhCali;
					SysState.AtpsRaParam.TDP = calc_dew_point_temp(SysState.AtpsRaParam.TDB, SysState.AtpsRaParam.RH);
					SysState.AtpsRaParam.TWB = calc_wet_bulb_temp(SysState.AtpsRaParam.TDB, SysState.AtpsRaParam.RH, SysParam.AppParam.Atmosphere);
					SysState.AtpsRaParam.HR = calc_humidity_ratio(SysState.AtpsRaParam.TDB, SysState.AtpsRaParam.RH, SysParam.AppParam.Atmosphere);
					SysState.AtpsRaParam.H = calc_enthalpy(SysState.AtpsRaParam.TDB, SysState.AtpsRaParam.RH, SysParam.AppParam.Atmosphere);
				}
				else if( DeviceType == AtpsMa )
				{
					SysState.AtpsMaParam.SensorFault = NoFault;
					
					SysState.AtpsMaParam.TDB = TDB + SysParam.AppParam.AtpsMaTempCali;
					SysState.AtpsMaParam.RH = RH + SysParam.AppParam.AtpsMaRhCali;
					SysState.AtpsMaParam.TDP = calc_dew_point_temp(SysState.AtpsMaParam.TDB, SysState.AtpsMaParam.RH);
					SysState.AtpsMaParam.TWB = calc_wet_bulb_temp(SysState.AtpsMaParam.TDB, SysState.AtpsMaParam.RH, SysParam.AppParam.Atmosphere);
					SysState.AtpsMaParam.HR = calc_humidity_ratio(SysState.AtpsMaParam.TDB, SysState.AtpsMaParam.RH, SysParam.AppParam.Atmosphere);
					SysState.AtpsMaParam.H = calc_enthalpy(SysState.AtpsMaParam.TDB, SysState.AtpsMaParam.RH, SysParam.AppParam.Atmosphere);
				}
				else if( DeviceType == AtpsExa )
				{
					SysState.AtpsExaParam.SensorFault = NoFault; 
					
					SysState.AtpsExaParam.TDB = TDB + SysParam.AppParam.AtpsExaTempCali;
					SysState.AtpsExaParam.RH = RH + SysParam.AppParam.AtpsExaRhCali;
					SysState.AtpsExaParam.TDP = calc_dew_point_temp(SysState.AtpsExaParam.TDB, SysState.AtpsExaParam.RH);
					SysState.AtpsExaParam.TWB = calc_wet_bulb_temp(SysState.AtpsExaParam.TDB, SysState.AtpsExaParam.RH, SysParam.AppParam.Atmosphere);
					SysState.AtpsExaParam.HR = calc_humidity_ratio(SysState.AtpsExaParam.TDB, SysState.AtpsExaParam.RH, SysParam.AppParam.Atmosphere);
					SysState.AtpsExaParam.H = calc_enthalpy(SysState.AtpsExaParam.TDB, SysState.AtpsExaParam.RH, SysParam.AppParam.Atmosphere);
				}
				else if( DeviceType == AtpsRooma )
				{
					SysState.AtpsRoomaParam.SensorFault = NoFault;
					
					SysState.AtpsRoomaParam.TDB = TDB + SysParam.AppParam.AtpsRoomaTempCali;
					SysState.AtpsRoomaParam.RH = RH + SysParam.AppParam.AtpsRoomaRhCali;
					SysState.AtpsRoomaParam.TDP = calc_dew_point_temp(SysState.AtpsRoomaParam.TDB, SysState.AtpsRoomaParam.RH);
					SysState.AtpsRoomaParam.TWB = calc_wet_bulb_temp(SysState.AtpsRoomaParam.TDB, SysState.AtpsRoomaParam.RH, SysParam.AppParam.Atmosphere);
					SysState.AtpsRoomaParam.HR = calc_humidity_ratio(SysState.AtpsRoomaParam.TDB, SysState.AtpsRoomaParam.RH, SysParam.AppParam.Atmosphere);
					SysState.AtpsRoomaParam.H = calc_enthalpy(SysState.AtpsRoomaParam.TDB, SysState.AtpsRoomaParam.RH, SysParam.AppParam.Atmosphere);
				}
				else if( DeviceType == AtpsCoola )
				{
					SysState.AtpsCoolaParam.SensorFault = NoFault;
					
					SysState.AtpsCoolaParam.TDB = TDB + SysParam.AppParam.AtpsCoolaTempCali;
					SysState.AtpsCoolaParam.RH = RH + SysParam.AppParam.AtpsCoolaRhCali;
					SysState.AtpsCoolaParam.TDP = calc_dew_point_temp(SysState.AtpsCoolaParam.TDB, SysState.AtpsCoolaParam.RH);
					SysState.AtpsCoolaParam.TWB = calc_wet_bulb_temp(SysState.AtpsCoolaParam.TDB, SysState.AtpsCoolaParam.RH, SysParam.AppParam.Atmosphere);
					SysState.AtpsCoolaParam.HR = calc_humidity_ratio(SysState.AtpsCoolaParam.TDB, SysState.AtpsCoolaParam.RH, SysParam.AppParam.Atmosphere);
					SysState.AtpsCoolaParam.H = calc_enthalpy(SysState.AtpsCoolaParam.TDB, SysState.AtpsCoolaParam.RH, SysParam.AppParam.Atmosphere);
				}
				else if( DeviceType == AtpsHeata )
				{
					SysState.AtpsHeataParam.SensorFault = NoFault;
					
					SysState.AtpsHeataParam.TDB = TDB + SysParam.AppParam.AtpsHeataTempCali;
					SysState.AtpsHeataParam.RH = RH + SysParam.AppParam.AtpsHeataRhCali;
					SysState.AtpsHeataParam.TDP = calc_dew_point_temp(SysState.AtpsHeataParam.TDB, SysState.AtpsHeataParam.RH);
					SysState.AtpsHeataParam.TWB = calc_wet_bulb_temp(SysState.AtpsHeataParam.TDB, SysState.AtpsHeataParam.RH, SysParam.AppParam.Atmosphere);
					SysState.AtpsHeataParam.HR = calc_humidity_ratio(SysState.AtpsHeataParam.TDB, SysState.AtpsHeataParam.RH, SysParam.AppParam.Atmosphere);
					SysState.AtpsHeataParam.H = calc_enthalpy(SysState.AtpsHeataParam.TDB, SysState.AtpsHeataParam.RH, SysParam.AppParam.Atmosphere);
				}
				else if( DeviceType == AtpsHuma )
				{
					SysState.AtpsHumaParam.SensorFault = NoFault;
					
					SysState.AtpsHumaParam.TDB = TDB + SysParam.AppParam.AtpsHumaTempCali;
					SysState.AtpsHumaParam.RH = RH + SysParam.AppParam.AtpsHumaRhCali;
					SysState.AtpsHumaParam.TDP = calc_dew_point_temp(SysState.AtpsHumaParam.TDB, SysState.AtpsHumaParam.RH);
					SysState.AtpsHumaParam.TWB = calc_wet_bulb_temp(SysState.AtpsHumaParam.TDB, SysState.AtpsHumaParam.RH, SysParam.AppParam.Atmosphere);
					SysState.AtpsHumaParam.HR = calc_humidity_ratio(SysState.AtpsHumaParam.TDB, SysState.AtpsHumaParam.RH, SysParam.AppParam.Atmosphere);
					SysState.AtpsHumaParam.H = calc_enthalpy(SysState.AtpsHumaParam.TDB, SysState.AtpsHumaParam.RH, SysParam.AppParam.Atmosphere);
				}
				else if( DeviceType == AtpsPre )
				{
					SysState.AtpsPreParam.SensorFault = NoFault;
					
					SysState.AtpsPreParam.TDB = TDB + SysParam.AppParam.AtpsPreTempCali;
					SysState.AtpsPreParam.RH = RH + SysParam.AppParam.AtpsPreRhCali;
					SysState.AtpsPreParam.TDP = calc_dew_point_temp(SysState.AtpsPreParam.TDB, SysState.AtpsPreParam.RH);
					SysState.AtpsPreParam.TWB = calc_wet_bulb_temp(SysState.AtpsPreParam.TDB, SysState.AtpsPreParam.RH, SysParam.AppParam.Atmosphere);
					SysState.AtpsPreParam.HR = calc_humidity_ratio(SysState.AtpsPreParam.TDB, SysState.AtpsPreParam.RH, SysParam.AppParam.Atmosphere);
					SysState.AtpsPreParam.H = calc_enthalpy(SysState.AtpsPreParam.TDB, SysState.AtpsPreParam.RH, SysParam.AppParam.Atmosphere);
				}
				else if( DeviceType == AtpsRot )
				{
					SysState.AtpsRotParam.SensorFault = NoFault;
					
					SysState.AtpsRotParam.TDB = TDB + SysParam.AppParam.AtpsRotTempCali;
					SysState.AtpsRotParam.RH = RH + SysParam.AppParam.AtpsRotRhCali;
					SysState.AtpsRotParam.TDP = calc_dew_point_temp(SysState.AtpsRotParam.TDB, SysState.AtpsRotParam.RH);
					SysState.AtpsRotParam.TWB = calc_wet_bulb_temp(SysState.AtpsRotParam.TDB, SysState.AtpsRotParam.RH, SysParam.AppParam.Atmosphere);
					SysState.AtpsRotParam.HR = calc_humidity_ratio(SysState.AtpsRotParam.TDB, SysState.AtpsRotParam.RH, SysParam.AppParam.Atmosphere);
					SysState.AtpsRotParam.H = calc_enthalpy(SysState.AtpsRotParam.TDB, SysState.AtpsRotParam.RH, SysParam.AppParam.Atmosphere);
				}
			}	
			
			vTaskDelay( SysParam.AppParam.SamplingPeriod / portTICK_PERIOD_MS );	
		}
		break;
		
		case 3:
		{
			if( DeviceType == AtpsSa )
			{
				if( SysState.AtpsSaParam.SensorFault != Fault)
				{
					SysState.AtpsSaParam.SensorFault = Fault;
					SysState.AtpsSaParam.SensorFaultCnt++;
				}
			}
			else if( DeviceType == AtpsOa )
			{
				if( SysState.AtpsOaParam.SensorFault != Fault)
				{
					SysState.AtpsOaParam.SensorFault = Fault;
					SysState.AtpsOaParam.SensorFaultCnt++;
				}
			}
			else if( DeviceType == AtpsRa )
			{
				if( SysState.AtpsRaParam.SensorFault != Fault)
				{
					SysState.AtpsRaParam.SensorFault = Fault;
					SysState.AtpsRaParam.SensorFaultCnt++;
				}
			}
			else if( DeviceType == AtpsMa )
			{
				if( SysState.AtpsMaParam.SensorFault != Fault)
				{
					SysState.AtpsMaParam.SensorFault = Fault;
					SysState.AtpsMaParam.SensorFaultCnt++;
				}
			}
			else if( DeviceType == AtpsExa )
			{
				if( SysState.AtpsExaParam.SensorFault != Fault)
				{
					SysState.AtpsExaParam.SensorFault = Fault;
					SysState.AtpsExaParam.SensorFaultCnt++;
				}
			}
			else if( DeviceType == AtpsRooma )
			{
				if( SysState.AtpsRoomaParam.SensorFault != Fault)
				{
					SysState.AtpsRoomaParam.SensorFault = Fault;
					SysState.AtpsRoomaParam.SensorFaultCnt++;
				}
			}
			else if( DeviceType == AtpsCoola )
			{
				if( SysState.AtpsCoolaParam.SensorFault != Fault)
				{
					SysState.AtpsCoolaParam.SensorFault = Fault;
					SysState.AtpsCoolaParam.SensorFaultCnt++;
				}
			}
			else if( DeviceType == AtpsHeata )
			{
				if( SysState.AtpsHeataParam.SensorFault != Fault)
				{
					SysState.AtpsHeataParam.SensorFault = Fault;
					SysState.AtpsHeataParam.SensorFaultCnt++;
				}
			}
			else if( DeviceType == AtpsHuma )
			{
				if( SysState.AtpsHumaParam.SensorFault != Fault)
				{
					SysState.AtpsHumaParam.SensorFault = Fault;
					SysState.AtpsHumaParam.SensorFaultCnt++;
				}
			}
			else if( DeviceType == AtpsPre )
			{
				if( SysState.AtpsPreParam.SensorFault != Fault)
				{
					SysState.AtpsPreParam.SensorFault = Fault;
					SysState.AtpsPreParam.SensorFaultCnt++;
				}
			}
			else if( DeviceType == AtpsRot )
			{
				if( SysState.AtpsRotParam.SensorFault != Fault)
				{
					SysState.AtpsRotParam.SensorFault = Fault;
					SysState.AtpsRotParam.SensorFaultCnt++;
				}
			}
			
			
			I2C_Deinitialize( );			//I2C总线释放
			SensorPowerOff;					//关闭传感器电源
			
			vTaskDelay( 5000 / portTICK_PERIOD_MS );	//断电延时
			
			state = 1;
		}
		break;
	}
}


  





